package com.zhoujing.myrabbitmq.config;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * @author 周敬
 * @version 1.0
 * @createTime 2022/7/20-11:41-星期三
 *
 * 回调接口
 */
@Slf4j
@Component
    public class MyCallBack implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnsCallback {

    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * @PostConstruct注解：在对象加载完依赖注入后执行它，通常都是一些初始化的操作，但初始化可能依赖于注入的其他组件，所以要等依赖全部加载完再执行
     */
    @PostConstruct
    public void init(){
        // 注入
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnsCallback(this);
    }

    /**
     * 交换机确认回调方法
     *
     * 1、发送消息成功了
     *      1.1 correlationData 保存回调消息的ID及相关消息
     *      1.2 交换机收到的消息  ack = true
     *      1.3 cause null
     * 2、接收消息失败了
     *      2.1 correlationData 保存回调消息的ID及相关消息
     *      2.2 交换机收到的消息  ack = false
     *      2.3 cause 失败的相关原因
     *
     * @param correlationData 保存回调消息的ID及相关消息
     * @param ack             成功或失败
     * @param cause           失败的相关信息
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        String id = correlationData !=null ? correlationData.getId() : "";
        if(ack){
            log.info("交换机已经接收到了ID为：{}的消息",id);
        }else{
            log.error("交换机还未收到ID为：{}的消息，由于原因：{}",id,cause);
        }
    }

    /**
     * 消息传递过程中不可路由时将消息返回给消费者
     * @param returnedMessage 返回的消息
     */
    @SneakyThrows
    @Override
    public void returnedMessage(ReturnedMessage returnedMessage) {
        log.error("消息：{}，被交换机：{}退回，退回原因：{}，路由Key：{}"
        ,new String(returnedMessage.getMessage().getBody(),"UTF-8")
        ,returnedMessage.getExchange()
        ,returnedMessage.getReplyText()
        ,returnedMessage.getRoutingKey());
    }
}
